package com.frank.libandroid;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.databinding.ViewDataBinding;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;

import com.frank.libandroid.butterknife.ButterKnife;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class MultiAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public MultiAdapter(Class<ViewBinding>... binders) {
        this.binders = binders;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        try {
            Class<ViewBinding> generic = binders[viewType];

            Method method = generic.getMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
            ViewBinding binding = (ViewBinding) method.invoke(null, LayoutInflater.from(parent.getContext()), parent, false);
            View root = binding.getRoot();
            root.setTag(R.id.tag_binding, binding);
            ButterKnife.bindMultiAdapter(this, binding);
            return new RecyclerView.ViewHolder(root) {
            };
        } catch (NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    private final Class<ViewBinding>[] binders;


    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ViewBinding binding = (ViewBinding) holder.itemView.getTag(R.id.tag_binding);
        binding.getRoot().setTag(R.id.tag_bean, mList.get(position));
        onBindData(binding, mList.get(position));
    }

    protected void onBindData(ViewBinding binding, Object bean) {
        if (binding instanceof ViewDataBinding) {
            ((ViewDataBinding) binding).setVariable(1, bean);
        }
        Object tag = binding.getRoot().getTag(R.id.tag_bindMethod);
        if (tag != null) {
            Method method = (Method) tag;
            try {
                method.setAccessible(true);
                method.invoke(this, binding, bean);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    @Override
    public int getItemViewType(int position) {
        return mList.get(position).getItemViewType();
    }

    private List<ItemType> mList = new ArrayList<>();

    public void setData(List<ItemType> list) {
        mList.clear();
        if (list != null) {
            mList.addAll(list);
        }
        notifyDataSetChanged();
    }

    public void addData(List<ItemType> list) {
        if (list != null) {
            mList.addAll(list);
        }
        notifyDataSetChanged();
    }

}
